#ifndef _AI_ENGINE_H
#define _AI_ENGINE_H

#include <vector>
#include <cstdlib>
#include <ctime>
#include <QObject>

#include "Define.h"
#include "GameEngine.h"
#include "Player.h"
#include "Move.h"
#include "Board.h"
#include "InfosMoves.h"
#include "AIResult.h"

#include <iostream>
using namespace std;

class AIEngine : public QObject
{
	Q_OBJECT

	private:

    	//Plateau du jeu
        Board* board;
        
        //Tableau des 2 joueurs de la partie
        Player* playerTable[2];
        
        //Liste des coups joués de la partie
        vector<Move> movesList;
        
        //Liste temporaire pour stocker les "coups légaux"
        vector<Move> regularMovesListTemp;
        
        //Player en train de joué
        int currentPlayer;
        
        //Partie terminé?
        bool isFinished;
        
        //Coup possible
        vector<Move> movesJouables;
		vector<Move>* movesJouablesSaved;
		
		int INFINITY;
		
		//Id du player en train de faire l'évaluation
		int idEvaluationPlayer;
		
		vector<InfosMoves> movesSavedList;
		int numCurrentMove;
		
		int scorePattern[8][8];

		int cptMiniMax;
		int cptAlphaBeta;
		int alphabreak, betabreak;

	public:
	
		AIEngine();
		~AIEngine();
		
		//Fction de connection des modules
		void connecting( GameEngine* );



	public slots:
	
		//Selectionne le moveà jouer (traitement global)
		void chooseMove( GameEngine* );
	
	
	
	private:
	
		//Initialise la grille de score modèle
		void initializationScorePattern();
	
		//Fonction qui initialise le moteur d'IA
		void initialization(GameEngine*);

		//Choisit aléatoirement un coup à jouer
		Move randomMove();
		
		//MiniMax Function
		AIResult miniMax(int);
		
		//AlphaBeta Function
		AIResult alphaBeta( int, AIResult, AIResult );
		
		//Fonction d'évaluation
		AIResult evaluateGame();

		//Retourne le score
		AIResult getScore();

        //Joue un coup dans la partie
        bool playMove(Move);

		//Annule le dernier coup joué
		void undoLastMove();
		
        //MAJ des données du jeu après avoir joué un coup: MAJ othellier, MAJ Score
        bool updateGame(Move);
        //MAJ les pions de la ligne du coup joué
        void updateRow(Move);        
        //MAJ les pions de la colonne du coup joué
        void updateColumn(Move);
        //MAJ les pions des diagonales du coup joué
        void updateDiagonal(Move);
        //Retourne un pion
        void turnDownPawn(int,int);
        //MAJ des scores des joueurs après le retournement d'un pion
        void updateScore();
        //Définition des coups légaux
        void definingRegularMoves();
        //MAJ des coups légaux contenu ds 'regularMovesList' sur l'othellier
        void updateRegularMove();
        //Incrémentation du nb de 'coup légaux' des joueurs en fonction de la couleur
        void increaseRegularMove(ColorPawn);
        //Vérification d'un coup légal suivant plusieurs paramètres...
        bool checkRegularMove( int, int, int, int);
		void initializationSavingMove();
		void addMoveList(Move m);
		void nextPlayer();
		void saveCurrentPlayer();
		void saveRegularMoves();
		void savePawnTurnedDown(int x, int y);
		
		void affiche_movesJouables();
		
	/********* new version *******************/
		void updateScoreEvaluate(int, ColorPawn, int &, int &);
		AIResult evaluateGameEvolutive();
		
		
	signals:
		
		//Emet le coup à jouer de l'IA
		void sendingMove( int, int );
			

};

#endif
